﻿using NetWorkToolkit;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Colyseus;
using static NetWorkToolkit.ColyseusClient;
using System;
using System.Linq;

public static class CommandMsgId
{
    public const string Test = "test";
}

public class MessageManager
{

    private static MessageManager _instance;
    public static MessageManager Instance
    {
        get
        {
            if (_instance == null)
                _instance = new MessageManager();
            return _instance;
        }
    }

    private bool m_Initialize = false;

    private ColyseusClient client;

    private IMessageResp RespHandler;

    public void InitializeMessage()
    {
        if (m_Initialize) return;

        client = ColyseusClient.instance;

        RespHandler = new MessageResp();

        // 网络框架默认通信接口
        client.AddListener(MsgId.Commond, RespHandler.onCommandResp);
        client.AddListener(MsgId.DisConnect, RespHandler.onDisconnectResp);
        client.AddListener(MsgId.CreateANetObject, RespHandler.onCreateANetObjectResp);
        client.AddListener(MsgId.DestroyANetObject, RespHandler.onDestroyANetObjectResp);
        client.AddListener(MsgId.StartGame, RespHandler.onStartGameResp);
        client.AddListener(MsgId.EndGame, RespHandler.onEndGameResp);
        //client.AddListener(MsgId.UpdateRoomInfo, OnUpdateRoomInfoResp);
        client.AddListener(MsgId.UploadNetSyncModuleInfo, RespHandler.onUploadNetSyncModuleInfoResp);
        client.AddListener(MsgId.ChangeNetSyncModuleStatus, RespHandler.onChangeNetSyncModuleStatusResp);
        client.AddListener(MsgId.S2CUpdateNetSyncModuleInfo, RespHandler.onS2CUpdateNetSyncModuleInfoResp);
        client.AddListener(MsgId.ChangeOwnershipOfNetModule, RespHandler.onChangeOwnershipOfNetModuleResp);

        RespHandler.RegisterCommandResp();

        m_Initialize = true;
    }


    #region SendMessage    

    public void SendCommondMsg(string func, string param)
    {
        CommondInfo commond = new CommondInfo()
        {
            func = func,
            param = param,
        };
        client.SendMsg(MsgId.Commond, Target.All, commond);
    }

    public void SendConnectServerMsg(string host, string route)
    {
        client.ConnectToServer(host, route, RespHandler.onConnectResp);
    }


    public void SendLeaveRoomMsg()
    {
        client.LeaveRoom(RespHandler.onLeaveRoomResp);
    }

    public void SendCreateRoomMsg(string roomName = "JARoom", string roomPassword = "ja")
    {
        client.CreateRoom(roomName, roomPassword, RespHandler.onCreateRoomResp);
    }

    public void SendDestoryPlayerObjMsg()
    {
        client.SendMsg(MsgId.DestroyANetObject, Target.All, null);
    }

    public void SendRefreshRoomList()
    {
        client.GetAvailableRooms(RespHandler.onUpdateRoomInfoResp);
    }

    /// <summary>
    /// 发送加入通过唯一标识加入房间的指令
    /// </summary>
    /// <param name="roomid">房间唯一标识,不是房间名称</param>
    /// <param name="password">房间密码</param>
    public void SendJoinRoomByIdMsg(string roomid, string password = "ja")
    {
        client.JoinRoom(roomid, password, RespHandler.onJoinRoomResp);
    }

    /// <summary>
    /// 发送游戏开始消息，此后玩家将无法加入该房间
    /// </summary>
    public void SendStartGameMsg()
    {
        client.SendMsg(MsgId.StartGame, Target.All, null);
    }

    /// <summary>
    /// 发送游戏结束消息,此后玩家将可以加入该房间
    /// </summary>
    public void SendEndGameMsg()
    {
        client.SendMsg(MsgId.EndGame, Target.Server, null);
    }

    public void SendUploadAPartNetSyncModule(List<NetSyncModule> ms)
    {
        Debug.Log("[SendUploadAPartNetSyncModule]");
        NSMInfo info;
        info.datas = new NSMC[ms.Count];
        for (int i = 0; i < ms.Count; i++)
        {
            PlayerMe.Instance.AddNetModule(ms[i].ModuleId, ms[i]);
            info.datas[i].Set(ms[i].transform.position, ms[i].transform.rotation, ms[i].ModuleId, "0");
        }

        // 只有房主会向服务的发送同步模块的数据
        if (PlayerMe.Instance.GetOwnerPlayerNetObj.IsRoomOwner)
            client.SendMsg(MsgId.UploadNetSyncModuleInfo, Target.Owner, info);
    }

    public void SendRemoveNSM(string id)
    {
        client.SendMsg(MsgId.RemoveNSM, Target.Server, id);
        var go = PlayerMe.Instance.GetNetModuleById(id);
        go.SetSync(false,true);
        PlayerMe.Instance.RemoveNetModule(id);
        GameObject.DestroyImmediate(go);
    }


    /// <summary>
    /// 发送给服务端更新NetModule状态-->位置状态和占有状态
    /// </summary>
    public void SendChangeNetSyncModuleStatusMsg(Vector3 pos, Quaternion qua, string id, string belongid = "", bool holdon = true)
    {
        NSMC n = new NSMC();
        n.pose = new float[7] { pos.x, pos.y, pos.z, qua.x, qua.y, qua.z, qua.w };
        n.BelongId = belongid;
        n.ModuleId = id;
        n.Holdon = holdon;
        client.SendMsg(MsgId.ChangeNetSyncModuleStatus, Target.Owner, n);
    }


    /// <summary>
    /// 所有用户加入房间后都需调用该方法，用于---> 当变成房主时 驱动服务端同步发送消息
    /// </summary>
    public void SendStartS2CUpdateNetModuleInfoMsg()
    {
        Debug.Log("[SendStartS2CUpdateNetModuleInfoMsg]");

        ClientUpdator.Instance.StartCoroutine(SyncRun());
    }
    private IEnumerator SyncRun()
    {
        while (true)
        {
            yield return new WaitForSeconds(1f / 30);
            if (PlayerMe.Instance.GetOwnerPlayerNetObj.IsRoomOwner)
            {
                ColyseusClient.instance.SendMsg(MsgId.S2CUpdateNetSyncModuleInfo, Target.Server, "nihao");
            }
        }
    }

    public void SendC2SUploadANetSyncModuleInfo(Vector3 pos, Quaternion qua, string id, string belongid = "", bool holdon = true)
    {
        NSMC n = new NSMC();
        n.pose = new float[7] { pos.x, pos.y, pos.z, qua.x, qua.y, qua.z, qua.w };
        n.BelongId = belongid;
        n.ModuleId = id;
        n.Holdon = holdon;
        client.SendMsg(MsgId.C2SUploadNetSyncModuleInfo, Target.Owner, n);
    }

    public void SendChangeOwnershipOfNetModuleMsg(string mid, bool holdon)
    {
        Debug.LogError(holdon.ToString());
        NetSyncModuleStatus status;
        status.moduleid = mid;
        status.belongid = ColyseusClient.instance.SessionID;
        status.holdon = holdon.ToString();
        client.SendMsg(MsgId.ChangeOwnershipOfNetModule, Target.All, status);
    }

    #endregion


}
